//@version=6
// ============================================================================
//  Quasimodo QM Pattern, QML, BOS & Liquidity Sweep [LunqFX]
// ----------------------------------------------------------------------------
//  Finds the quasimodo (QM) reversal structure — left shoulder, a head that
//  sweeps the shoulder's liquidity, a break of structure (BOS) the other way —
//  marks the QM level (QML) at the left shoulder, then follows what price
//  does next: does it come back to the QML, and from there does it reach the
//  targets or break the head. Every finished pattern is filed, so the HUD
//  shows how the QM has actually played out on this symbol.
//
//  NON-REPAINTING: swings are confirmed pivots; the BOS, the QML tap, target
//  hits and failures are decided on closed bars. No request.security.
// ============================================================================
indicator("Quasimodo QM Pattern, QML, BOS & Liquidity Sweep [LunqFX]", "Quasimodo [LunqFX]",
     overlay = true, max_lines_count = 300, max_labels_count = 300, max_boxes_count = 100, max_polylines_count = 50)

// ─────────────────────────────────────────────────────────────────────────
//  INPUTS
// ─────────────────────────────────────────────────────────────────────────
gM = "Pattern"
pivLen   = input.int(5, "Swing strength", minval = 2, maxval = 20, group = gM, tooltip = "Bars on each side that confirm a swing high or low. Higher = bigger, fewer patterns.")
minSweep = input.float(0.1, "Min. head sweep (× ATR)", minval = 0.0, maxval = 5.0, step = 0.05, group = gM,
     tooltip = "How far the head must go beyond the left shoulder to count as a liquidity sweep.")
zoneAtr  = input.float(0.25, "QML zone depth (× ATR)", minval = 0.05, maxval = 2.0, step = 0.05, group = gM,
     tooltip = "The QML zone runs from the left shoulder's extreme this far back toward price. A trade into the zone counts as a QML tap.")
maxWait  = input.int(60, "Bars to wait for the QML tap", minval = 5, maxval = 500, group = gM)
maxRun   = input.int(120, "Bars after the tap", minval = 5, maxval = 1000, group = gM, tooltip = "After this many bars without a target or failure the pattern is closed as expired.")

gD = "Drawing"
showLeg  = input.bool(true, "Pattern legs (LS → H → BOS)", group = gD)
showZone = input.bool(true, "QML zone", group = gD)
showTgt  = input.bool(true, "Targets and invalidation", group = gD)
keepN    = input.int(3, "Patterns drawn", minval = 1, maxval = 20, group = gD, tooltip = "Finished patterns older than this are removed from the chart. The track record keeps all of them.")
lblSize  = input.string("Normal", "Label size", options = ["Small", "Normal", "Large"], group = gD)

gH = "HUD"
showHud = input.bool(true, "Show HUD", group = gH)
hudPos  = input.string("Bottom Center", "Position", options = ["Bottom Center", "Top Center", "Bottom Right", "Top Right"], group = gH)
hudSize = input.string("Normal", "Text size", options = ["Small", "Normal", "Large"], group = gH)

gA = "Alerts"
alBos  = input.bool(true, "Alert: QM formed (BOS)", group = gA)
alTap  = input.bool(true, "Alert: QML tapped", group = gA)
alRes  = input.bool(true, "Alert: target hit / failed", group = gA)

candOn_ = input.bool(true, "Neon candles", group = "Visuals")
candGlw = input.bool(true, "Glow candles", group = "Visuals", tooltip = "Each body is drawn in four bands that brighten towards the close, so the candle reads in the direction it moved. Off = flat translucent bodies.")

// ─────────────────────────────────────────────────────────────────────────
//  THEME — electric blue / neon red, white structure
// ─────────────────────────────────────────────────────────────────────────
bgLum   = 0.2126 * color.r(chart.bg_color) + 0.7152 * color.g(chart.bg_color) + 0.0722 * color.b(chart.bg_color)
isLight = bgLum > 128
UP      = isLight ? #1D6FE0 : #2E9BFF
DN      = isLight ? #D61F3C : #FF3355
WH      = isLight ? #1A1D24 : #F2F4F8   // structure lines and labels
GREY    = isLight ? #8A8F9C : #6B7080
TXT     = isLight ? #1A1D24 : #E8EAF0
MUTE    = isLight ? #5E6472 : #8F96A6
PANEL   = isLight ? #FFFFFF : #0A0C12
ROW     = isLight ? #EEF1F6 : #151925
INK     = #0A0C12
NONE    = color.new(color.black, 100)

lSize = lblSize == "Small" ? size.small : lblSize == "Large" ? size.large : size.normal
hSize = hudSize == "Small" ? size.small : hudSize == "Large" ? size.large : size.normal

px(float v) =>
    str.tostring(v, format.mintick)

pct(int a, int b) =>
    b > 0 ? str.tostring(a * 100.0 / b, "0") + "%" : "—"

// ─────────────────────────────────────────────────────────────────────────
//  SWINGS — alternating confirmed pivots
// ─────────────────────────────────────────────────────────────────────────
atr  = ta.atr(14)
ph   = ta.pivothigh(high, pivLen, pivLen)
pl   = ta.pivotlow(low, pivLen, pivLen)
pBar = bar_index - pivLen

var array<int>   sT = array.new_int()     // 1 high, -1 low
var array<float> sP = array.new_float()
var array<int>   sB = array.new_int()

addSwing(int t, float p, int b) =>
    n = array.size(sT)
    if n > 0 and array.get(sT, n - 1) == t
        // same side twice: keep the more extreme one
        if t == 1 ? p > array.get(sP, n - 1) : p < array.get(sP, n - 1)
            array.set(sP, n - 1, p)
            array.set(sB, n - 1, b)
    else
        array.push(sT, t)
        array.push(sP, p)
        array.push(sB, b)
        if array.size(sT) > 20
            array.shift(sT)
            array.shift(sP)
            array.shift(sB)
    0   // explicit result, so the if/else branches above are not used as the return value

if not na(ph) and not na(pl)
    // both on one bar: take the one the bar's close is further from
    if math.abs(ph - close[pivLen]) > math.abs(close[pivLen] - pl)
        addSwing(1, ph, pBar)
    else
        addSwing(-1, pl, pBar)
else if not na(ph)
    addSwing(1, ph, pBar)
else if not na(pl)
    addSwing(-1, pl, pBar)

// ─────────────────────────────────────────────────────────────────────────
//  STATE
//  stage 0 searching · 3 QM formed (BOS), waiting for the QML tap
//  stage 4 QML tapped, targets running
//  dir -1 bearish QM (head above, sell side) · 1 bullish QM (head below)
// ─────────────────────────────────────────────────────────────────────────
var int   stage = 0
var int   dir   = 0
var float lsP = na
var int   lsB = na
var float midP = na     // the swing between shoulder and head (its break is the BOS)
var int   midB = na
var float hdP = na
var int   hdB = na
var float ext = na      // the BOS leg extreme
var int   bosB = na
var int   tapB = na
var float zFar = na     // QML zone edge toward price
var float t1 = na
var float t2 = na
var int   hitMax = 0
var int   usedHead = na

var line  qLn = na
var box   qBx = na
var label qLb = na
var line  t1Ln = na
var line  t2Ln = na
var line  ivLn = na
var label t1Lb = na
var label t2Lb = na

// record: 0 bullish, 1 bearish
var array<int> rForm = array.new_int(2, 0)
var array<int> rTap  = array.new_int(2, 0)
var array<int> rT1   = array.new_int(2, 0)
var array<int> rT2   = array.new_int(2, 0)
var array<int> rFail = array.new_int(2, 0)
var array<int> rWait = array.new_int(2, 0)   // bars from BOS to tap, summed

// registry: keep only the last N patterns on the chart
var int mid = 0
var array<line>     gLn  = array.new<line>()
var array<int>      gLnI = array.new_int()
var array<label>    gLb  = array.new<label>()
var array<int>      gLbI = array.new_int()
var array<box>      gBx  = array.new<box>()
var array<int>      gBxI = array.new_int()
var array<polyline> gPl  = array.new<polyline>()
var array<int>      gPlI = array.new_int()

bump(array<int> a, int i, int add) =>
    array.set(a, i, array.get(a, i) + add)
regLn(line o) =>
    array.push(gLn, o)
    array.push(gLnI, mid)
regLb(label o) =>
    array.push(gLb, o)
    array.push(gLbI, mid)
regBx(box o) =>
    array.push(gBx, o)
    array.push(gBxI, mid)
regPl(polyline o) =>
    array.push(gPl, o)
    array.push(gPlI, mid)
prune(int upTo) =>
    while array.size(gLnI) > 0 and array.get(gLnI, 0) <= upTo
        line.delete(array.shift(gLn))
        array.shift(gLnI)
    while array.size(gLbI) > 0 and array.get(gLbI, 0) <= upTo
        label.delete(array.shift(gLb))
        array.shift(gLbI)
    while array.size(gBxI) > 0 and array.get(gBxI, 0) <= upTo
        box.delete(array.shift(gBx))
        array.shift(gBxI)
    while array.size(gPlI) > 0 and array.get(gPlI, 0) <= upTo
        polyline.delete(array.shift(gPl))
        array.shift(gPlI)

evBos  = false
evTap  = false
evHit  = 0
evFrom = 0
evFail = false
evEnd  = false

closeOut(string txt, color c, color tc, bool done) =>
    // the result is written into a label the pattern already has, so nothing floats loose on the chart:
    // a completed QM into its T2 label, every other ending into the QML label
    if done and not na(t2Lb)
        label.set_text(t2Lb, txt + " · T2 " + px(t2))
    else if not na(qLb)
        label.set_text(qLb, txt + " · QML " + px(lsP))
        label.set_color(qLb, c)
        label.set_textcolor(qLb, tc)
    else
        regLb(label.new(bar_index, dir == -1 ? low : high, txt, style = dir == -1 ? label.style_label_up : label.style_label_down,
             color = c, textcolor = tc, size = lSize))
    line.set_x2(qLn, bar_index)
    box.set_right(qBx, bar_index)
    label.set_x(qLb, bar_index)
    prune(mid - keepN)

// ─────────────────────────────────────────────────────────────────────────
//  STATE MACHINE — closed bars only
// ─────────────────────────────────────────────────────────────────────────
if barstate.isconfirmed and not na(atr)
    qml = lsP

    // ── 4 · QML tapped: targets or failure beyond the head
    if stage == 4
        evFrom := hitMax
        failNow = dir == -1 ? close > hdP : close < hdP
        if failNow
            evFail := true
        else
            for k = 1 to 2
                tk = k == 1 ? t1 : t2
                if hitMax == k - 1 and (dir == -1 ? low <= tk : high >= tk)
                    hitMax := k
                    evHit := k
        expired = bar_index - tapB > maxRun
        if evFail or hitMax == 2 or expired
            d = dir == 1 ? 0 : 1
            bump(rT1, d, hitMax >= 1 ? 1 : 0)
            bump(rT2, d, hitMax >= 2 ? 1 : 0)
            bump(rFail, d, evFail ? 1 : 0)
            evEnd := true
            txt = hitMax == 2 ? "QM COMPLETE · " + str.tostring(bar_index - tapB) + " bars" : evFail ? "✕ HEAD BROKEN" + (hitMax == 1 ? " · T1 reached" : "") : "EXPIRED" + (hitMax == 1 ? " · T1 reached" : "")
            closeOut(txt, hitMax == 2 ? WH : color.new(GREY, 0), INK, hitMax == 2)
            stage := 0
            dir := 0

    // ── 3 · QM formed: wait for price to come back to the QML
    if stage == 3
        ext := dir == -1 ? math.min(ext, low) : math.max(ext, high)
        headBroken = dir == -1 ? close > hdP : close < hdP
        tapped = dir == -1 ? high >= zFar : low <= zFar
        if tapped and not headBroken
            stage := 4
            evTap := true
            tapB := bar_index
            hitMax := 0
            bump(rTap, dir == 1 ? 0 : 1, 1)
            bump(rWait, dir == 1 ? 0 : 1, bar_index - bosB)
            t1 := ext
            t2 := qml - (hdP - ext)          // the head-to-BOS leg, measured again from the QML
            mc = dir == -1 ? DN : UP
            regLb(label.new(bar_index, dir == -1 ? high : low, "QML TAP", style = dir == -1 ? label.style_label_down : label.style_label_up,
                 color = mc, textcolor = dir == -1 ? color.white : INK, size = lSize))
            if showTgt
                t1Ln := line.new(bar_index, t1, bar_index + 1, t1, color = color.new(WH, 25), width = 1, style = line.style_dashed)
                t2Ln := line.new(bar_index, t2, bar_index + 1, t2, color = WH, width = 2)
                ivLn := line.new(bar_index, hdP, bar_index + 1, hdP, color = color.new(mc, 30), width = 1, style = line.style_dotted)
                t1Lb := label.new(bar_index + 1, t1, "T1 · BOS EXTREME " + px(t1), style = label.style_label_left, color = color.new(PANEL, 10), textcolor = WH, size = size.small)
                t2Lb := label.new(bar_index + 1, t2, "T2 · LEG PROJECTION " + px(t2), style = label.style_label_left, color = WH, textcolor = INK, size = size.small)
                // the head sits right next to the QML, so the invalidation joins the QML label instead of stacking on it
                label.set_text(qLb, (dir == -1 ? "▼ " : "▲ ") + "QML " + px(qml) + " · INVALID " + px(hdP))
                regLn(t1Ln)
                regLn(t2Ln)
                regLn(ivLn)
                regLb(t1Lb)
                regLb(t2Lb)
        else if headBroken or bar_index - bosB > maxWait
            // never came back, or the head gave way first
            evEnd := true
            closeOut(headBroken ? "✕ HEAD BROKEN · no QML tap" : "QML MISSED", color.new(GREY, 0), INK, false)
            stage := 0
            dir := 0

    // ── 0 · searching: shoulder → middle swing → head, then a close through the middle swing
    if stage == 0 and array.size(sT) >= 3
        n = array.size(sT)
        tA = array.get(sT, n - 3)
        pA = array.get(sP, n - 3)
        bA = array.get(sB, n - 3)
        pM = array.get(sP, n - 2)
        bM = array.get(sB, n - 2)
        pH_ = array.get(sP, n - 1)
        bH = array.get(sB, n - 1)
        // one pattern per head; the BOS is the first close through the middle swing once the head is confirmed
        fresh = na(usedHead) or bH != usedHead
        // bearish QM: high (LS) · low · higher high (head) · close below the low
        bear = tA == 1 and pM < pA and pH_ > pA + minSweep * atr and close < pM
        // bullish QM: low (LS) · high · lower low (head) · close above the high
        bull = tA == -1 and pM > pA and pH_ < pA - minSweep * atr and close > pM
        if fresh and (bear or bull)
            stage := 3
            dir := bear ? -1 : 1
            evBos := true
            usedHead := bH
            mid += 1
            lsP := pA
            lsB := bA
            midP := pM
            midB := bM
            hdP := pH_
            hdB := bH
            ext := bear ? low : high
            bosB := bar_index
            zFar := bear ? lsP - zoneAtr * atr : lsP + zoneAtr * atr
            bump(rForm, bear ? 1 : 0, 1)
            mc = bear ? DN : UP
            if showLeg
                pts = array.from(chart.point.from_index(lsB, lsP), chart.point.from_index(midB, midP), chart.point.from_index(hdB, hdP), chart.point.from_index(bar_index, close))
                regPl(polyline.new(pts, curved = false, xloc = xloc.bar_index, line_color = color.new(WH, 15), line_width = 2))
                regLb(label.new(lsB, lsP, "LS", style = bear ? label.style_label_down : label.style_label_up, color = color.new(PANEL, 0), textcolor = WH, size = size.small))
                regLb(label.new(hdB, hdP, "HEAD · SWEEP", style = bear ? label.style_label_down : label.style_label_up, color = mc, textcolor = bear ? color.white : INK, size = size.small))
                regLn(line.new(midB, midP, bar_index, midP, color = mc, width = 2, style = line.style_dashed))
                regLb(label.new(bar_index, midP, "BOS", style = label.style_label_left, color = NONE, textcolor = mc, size = size.small))
            if showZone
                qBx := box.new(lsB, math.max(lsP, zFar), bar_index + 1, math.min(lsP, zFar), border_color = color.new(mc, 30), border_width = 1,
                     bgcolor = color.new(mc, 82))
                qLn := line.new(lsB, lsP, bar_index + 1, lsP, color = mc, width = 2)
                qLb := label.new(bar_index + 1, lsP, (bear ? "▼ " : "▲ ") + "QML " + px(lsP), style = label.style_label_left, color = mc, textcolor = bear ? color.white : INK, size = lSize)
                regBx(qBx)
                regLn(qLn)
                regLb(qLb)

// running drawings follow the current bar
if stage >= 3
    line.set_x2(qLn, bar_index + 2)
    box.set_right(qBx, bar_index + 2)
    label.set_x(qLb, bar_index + 2)
if stage == 4 and showTgt
    line.set_x2(t1Ln, bar_index + 2)
    line.set_x2(t2Ln, bar_index + 2)
    line.set_x2(ivLn, bar_index + 2)
    label.set_x(t1Lb, bar_index + 2)
    label.set_x(t2Lb, bar_index + 2)
if evHit > 0 and showTgt
    for k = evFrom + 1 to evHit
        lb = k == 1 ? t1Lb : t2Lb
        label.set_text(lb, "✓ " + label.get_text(lb))
if evEnd and showTgt and not na(t1Ln) and stage == 0
    line.set_x2(t1Ln, bar_index)
    line.set_x2(t2Ln, bar_index)
    line.set_x2(ivLn, bar_index)
    label.set_x(t1Lb, bar_index + 1)
    label.set_x(t2Lb, bar_index + 1)
    t1Ln := na
    t2Ln := na
    ivLn := na
    t1Lb := na
    t2Lb := na

// ─────────────────────────────────────────────────────────────────────────
//  HUD — one horizontal strip: stage tracker · live levels · track record
// ─────────────────────────────────────────────────────────────────────────
hPos = hudPos == "Bottom Center" ? position.bottom_center : hudPos == "Top Center" ? position.top_center : hudPos == "Bottom Right" ? position.bottom_right : position.top_right
var table hud = na

hc(int c, int r, string t, color fg, color bg, string al = text.align_center) =>
    table.cell(hud, c, r, t, text_color = fg, bgcolor = bg, text_size = hSize, text_halign = al)

chip(int c, int step, string name) =>
    // step done = filled, current = outlined dot, ahead = muted
    cur = stage == 0 ? 0 : stage == 3 ? 4 : 4 + hitMax + 1
    mc = dir == -1 ? DN : UP
    done = stage > 0 and step < cur
    now_ = stage > 0 and step == cur
    hc(c, 0, (done ? "✓ " : now_ ? "◉ " : "○ ") + name, done ? (dir == -1 ? color.white : INK) : now_ ? mc : MUTE, done ? mc : ROW)

if barstate.islast and showHud
    table.delete(hud)
    hud := table.new(hPos, 7, 3, bgcolor = PANEL, border_color = PANEL, border_width = 3, frame_color = color.new(stage > 0 ? (dir == -1 ? DN : UP) : GREY, 20), frame_width = 1)
    mc = dir == -1 ? DN : UP
    // row 0 — what is happening now
    hc(0, 0, stage == 0 ? "QUASIMODO · SCANNING" : (dir == -1 ? "▼ BEARISH QM" : "▲ BULLISH QM"), stage == 0 ? TXT : (dir == -1 ? color.white : INK), stage == 0 ? ROW : mc, text.align_left)
    chip(1, 1, "LEFT SHOULDER")
    chip(2, 2, "HEAD SWEEP")
    chip(3, 3, "BOS")
    chip(4, 4, "QML TAP")
    chip(5, 5, "T1")
    chip(6, 6, "T2")
    // row 1 — the levels that matter
    dist = stage == 3 and atr > 0 ? math.abs(close - zFar) / atr : na
    hc(0, 1, stage == 0 ? "waiting for LS → head → BOS" : stage == 3 ? "QML " + px(lsP) + " · " + str.tostring(dist, "0.0") + " ATR away" : "QML tapped · in play", stage == 0 ? MUTE : TXT, ROW, text.align_left)
    hc(1, 1, stage == 0 ? "—" : px(lsP), stage == 0 ? MUTE : TXT, ROW)
    hc(2, 1, stage == 0 ? "—" : px(hdP), stage == 0 ? MUTE : TXT, ROW)
    hc(3, 1, stage == 0 ? "—" : px(midP), stage == 0 ? MUTE : TXT, ROW)
    hc(4, 1, stage == 0 ? "—" : px(zFar), stage == 0 ? MUTE : TXT, ROW)
    hc(5, 1, stage == 4 ? px(t1) : "—", stage == 4 ? TXT : MUTE, ROW)
    hc(6, 1, stage == 4 ? px(t2) : "—", stage == 4 ? TXT : MUTE, ROW)
    // row 2 — how the QM has played out on this symbol
    nF = array.sum(rForm)
    nTp = array.sum(rTap)
    nT1 = array.sum(rT1)
    nT2 = array.sum(rT2)
    nFl = array.sum(rFail)
    avgW = nTp > 0 ? array.sum(rWait) * 1.0 / nTp : na
    hc(0, 2, "TRACK RECORD · " + str.tostring(nF) + " QM on this chart", WH, PANEL, text.align_left)
    hc(1, 2, "QML reached " + pct(nTp, nF), TXT, PANEL)
    hc(2, 2, "▲ " + pct(array.get(rTap, 0), array.get(rForm, 0)) + " · ▼ " + pct(array.get(rTap, 1), array.get(rForm, 1)), MUTE, PANEL)
    hc(3, 2, "avg " + (na(avgW) ? "—" : str.tostring(avgW, "0")) + " bars to QML", MUTE, PANEL)
    hc(4, 2, "after tap:", MUTE, PANEL)
    hc(5, 2, "T1 " + pct(nT1, nTp) + " · T2 " + pct(nT2, nTp), WH, PANEL)
    hc(6, 2, "head broken " + pct(nFl, nTp), MUTE, PANEL)

// ─────────────────────────────────────────────────────────────────────────
//  ALERTS
// ─────────────────────────────────────────────────────────────────────────
if alBos and evBos
    alert(syminfo.ticker + " " + (dir == -1 ? "bearish" : "bullish") + " quasimodo formed · QML " + px(lsP) + " · head " + px(hdP), alert.freq_once_per_bar_close)
if alTap and evTap
    alert(syminfo.ticker + " QML tapped at " + px(lsP) + " · T1 " + px(t1) + " · T2 " + px(t2) + " · invalid beyond " + px(hdP), alert.freq_once_per_bar_close)
if alRes and evHit > 0
    alert(syminfo.ticker + " quasimodo T" + str.tostring(evHit) + " hit", alert.freq_once_per_bar_close)
if alRes and evFail
    alert(syminfo.ticker + " quasimodo failed: close beyond the head", alert.freq_once_per_bar_close)

alertcondition(evBos, "QM formed", "{{ticker}} quasimodo formed (BOS)")
alertcondition(evTap, "QML tapped", "{{ticker}} QML tapped")
alertcondition(evHit > 0, "QM target hit", "{{ticker}} quasimodo target hit")
alertcondition(evFail, "QM failed", "{{ticker}} quasimodo failed")

// ─────────────────────────────────────────────────────────────────────────
//  GLOW CANDLES (LunqFX house style)
// ─────────────────────────────────────────────────────────────────────────
GLOW_UP_DARK  = #2E9BFF
GLOW_DN_DARK  = #FF3355
GLOW_UP_LIGHT = #1D6FE0
GLOW_DN_LIGHT = #D61F3C

glowUp   = isLight ? GLOW_UP_LIGHT : GLOW_UP_DARK
glowDn   = isLight ? GLOW_DN_LIGHT : GLOW_DN_DARK
glowEdge = close >= open ? glowUp : glowDn
glowOn   = candOn_ and candGlw
GLOW_NONE = color.new(color.black, 100)

plotcandle(candOn_ and not glowOn ? open : na, high, low, close, "Candles", color = color.new(glowEdge, 24), wickcolor = color.new(glowEdge, 18), bordercolor = glowEdge, display = display.pane)

gQ = (close - open) / 4.0
plotcandle(glowOn ? open : na, glowOn ? math.max(open, close) : na, glowOn ? math.min(open, close) : na, glowOn ? close : na, "Glow mask", color = chart.bg_color, wickcolor = GLOW_NONE, bordercolor = chart.bg_color, display = display.pane)
plotcandle(glowOn ? open : na, glowOn ? math.max(open, open + gQ) : na, glowOn ? math.min(open, open + gQ) : na, glowOn ? open + gQ : na, "Glow band 1", color = color.new(glowEdge, 78), wickcolor = GLOW_NONE, bordercolor = GLOW_NONE, display = display.pane)
plotcandle(glowOn ? open + gQ : na, glowOn ? math.max(open + gQ, open + 2 * gQ) : na, glowOn ? math.min(open + gQ, open + 2 * gQ) : na, glowOn ? open + 2 * gQ : na, "Glow band 2", color = color.new(glowEdge, 58), wickcolor = GLOW_NONE, bordercolor = GLOW_NONE, display = display.pane)
plotcandle(glowOn ? open + 2 * gQ : na, glowOn ? math.max(open + 2 * gQ, open + 3 * gQ) : na, glowOn ? math.min(open + 2 * gQ, open + 3 * gQ) : na, glowOn ? open + 3 * gQ : na, "Glow band 3", color = color.new(glowEdge, 36), wickcolor = GLOW_NONE, bordercolor = GLOW_NONE, display = display.pane)
plotcandle(glowOn ? open + 3 * gQ : na, glowOn ? math.max(open + 3 * gQ, close) : na, glowOn ? math.min(open + 3 * gQ, close) : na, glowOn ? close : na, "Glow band 4", color = color.new(glowEdge, 8), wickcolor = GLOW_NONE, bordercolor = GLOW_NONE, display = display.pane)
plotcandle(glowOn ? open : na, glowOn ? high : na, glowOn ? low : na, glowOn ? close : na, "Glow wick", color = GLOW_NONE, wickcolor = color.new(glowEdge, 10), bordercolor = color.new(glowEdge, 30), display = display.pane)
